package com.hd123.rumba.gwt.widget2.server;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Random;

import junit.framework.TestCase;

import com.hd123.gwt.types.JsBigDecimal;
import com.hd123.rumba.exception.BusinessException;
import com.hd123.rumba.gwt.widget2.client.grid.RPageData;
import com.hd123.rumba.sql.biz.BResultPage;

/**
 * 测试{@link RPageDataConverter}
 * 
 * @author LiQi
 * 
 */
public class RPageDataConverterTest extends TestCase {

  private static final int DEFAULT_PAGE_SIZE = 10;
  private static final int DEFAULT_TOTAL_COUNT = 110;

  private BResultPage source;

  protected void setUp() throws Exception {
    super.setUp();
    source = createBResultPageWithPagingInfo();
  }

  public void testNullToNull() throws BusinessException {
    BResultPage source = null;
    Object dest = new RPageDataConverter().convert(source);
    assertEquals(null, dest);
  }

  public void testArrayToArray() throws BusinessException {
    // 填充source
    fillArrayInSource();

    // 打印source
    printSource();

    // 执行转换
    RPageData dest = new RPageDataConverter().convert(source);

    // 打印dest
    printDest(dest);

    // 比较转换结果
    assertEqualsPagingInfo(source, dest);
    for (int i = 0; i < source.getValues().size(); i++) {
      Object[] sourceRec = (Object[]) source.getValues().get(i);
      List destRec = (List) dest.getValues().get(i);
      assertEquals(sourceRec.length, destRec.size());

      for (int j = 0; j < sourceRec.length; j++) {
        Object sourceField = sourceRec[j];
        Object destField = destRec.get(j);

        if (sourceField == null)
          assertEquals(null, destField);
        else if (sourceField instanceof BigDecimal)
          assertEquals(((BigDecimal) sourceField).doubleValue(), ((JsBigDecimal) destField)
              .doubleValue(), 0);
        else if (sourceField instanceof Enum)
          assertEquals(((Enum) sourceField).name(), (String) destField);
        else
          assertEquals(sourceField, destField);
      }
    }
  }

  /**
   * 检查分页信息是否正确
   * 
   * @param source
   * @param dest
   */
  private void assertEqualsPagingInfo(BResultPage source, RPageData dest) {
    assertEquals(source.getElementCount(), dest.getTotalCount());
    assertEquals(source.getPageCount(), dest.getPageCount());
    assertEquals(source.getPage(), dest.getCurrentPage());
    assertEquals(source.getValues().size(), dest.getValues().size());
  }

  /**
   * 创建一个仅包含分页信息的BResultPage
   * 
   * @return
   */
  private BResultPage createBResultPageWithPagingInfo() {
    BResultPage result = new BResultPage();
    result.setElementCount(DEFAULT_TOTAL_COUNT);
    result.setPageCount(new Double(Math.ceil(DEFAULT_TOTAL_COUNT
        / new Double(DEFAULT_PAGE_SIZE).doubleValue())).intValue());
    result.setPageSize(DEFAULT_PAGE_SIZE);
    result.setPage(0);
    return result;
  }

  /**
   * 向source中填充数组
   * 
   */
  private void fillArrayInSource() {
    Random random = new Random();
    List sourceValues = new ArrayList();
    for (int i = 0; i < DEFAULT_PAGE_SIZE; i++) {
      Object[] sourceRec = new Object[10];
      sourceRec[0] = "string values";
      sourceRec[1] = new Integer(random.nextInt());
      sourceRec[2] = new Long(random.nextLong());
      sourceRec[3] = new Double(random.nextDouble());
      sourceRec[4] = new BigDecimal(random.nextDouble());
      sourceRec[5] = null;
      sourceRec[6] = new Date();
      sourceRec[7] = new java.sql.Date(random.nextLong());
      sourceRec[8] = TestEnum.values()[random.nextInt(TestEnum.values().length)];
      sourceValues.add(sourceRec);
    }
    source.setValues(sourceValues);
  }

  /**
   * 输出源数据到控制台
   * 
   */
  private void printSource() {
    System.out.println("[Source] 总记录数=" + source.getElementCount() + ", 总页数="
        + source.getPageCount() + ", 当前页=" + source.getPage() + ", 记录数="
        + source.getValues().size());
    for (Iterator<Object[]> i = source.getValues().iterator(); i.hasNext();) {
      Object[] sourceRec = i.next();
      for (Object sourceField : sourceRec) {
        System.out.print(sourceField == null ? "null" : (sourceField.getClass().getSimpleName()
            + ":" + sourceField));
        System.out.print("┃");
      }
      System.out.println();
    }
  }

  /**
   * 输出目标数据到控制台
   * 
   * @param dest
   */
  private void printDest(RPageData dest) {
    System.out.println("[Dest] 总记录数=" + dest.getTotalCount() + ", 总页数=" + dest.getPageCount()
        + ", 当前页=" + dest.getCurrentPage() + ", 记录数=" + dest.getValues().size());
    for (Iterator<List> i = dest.getValues().iterator(); i.hasNext();) {
      List destRec = i.next();
      for (Object destField : destRec) {
        System.out.print(destField == null ? "null"
            : (destField.getClass().getSimpleName() + ":" + destField));
        System.out.print("┃");
      }
      System.out.println();
    }
  }
}

enum TestEnum {
  ITEM1, ITEM2, ITEM3, ITEM4, ITEM5
}
